package spu

import (
	"context"
	"github.com/zeromicro/go-zero/core/logx"
	"gorm.io/gorm"
	"mall/common/excption"
	constans "mall/services/product/rpc/consts"
	"mall/services/product/rpc/internal/domain/bo"
	"mall/services/product/rpc/internal/mapper"
	"mall/services/product/rpc/internal/mapper/entity"
	"mall/services/product/rpc/internal/svc"
	"mall/services/product/rpc/pb"
	"time"
)

type SaveSpuLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewSaveSpuLogic(ctx context.Context, svcCtx *svc.ServiceContext) *SaveSpuLogic {
	return &SaveSpuLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

func (l *SaveSpuLogic) SaveSpu(in *pb.SaveSpuDTO) (*pb.SaveSpuVO, error) {
	// 1. query spu name
	spuBO := bo.SpuBO{}
	spuBO.Name = in.Name
	spuBO.ShopId = in.ShopId
	spuBO.CategoryId = in.CategoryId
	spuBO.NeStatus = constans.SpuTakeDown
	//spuModel := l.svcCtx.DBEngin
	spuMapper := mapper.NewSpuMapper[entity.SpuEntity]()
	selectCount, err := spuMapper.SelectCountCtx(l.ctx, l.svcCtx.DBEngin, spuBO)
	if err != nil {
		return nil, err
	}
	if selectCount > 0 {
		return nil, excption.NewErrCode(constans.SpuNameRepeatError)
	}
	// 1.1 builder request
	spuInfo := entity.SpuEntity{}
	spuInfo.BrandId = in.BrandId
	spuInfo.CategoryId = in.CategoryId
	spuInfo.ShopCategoryId = in.ShopCategoryId
	spuInfo.ShopId = in.ShopId
	spuInfo.Name = in.Name
	spuInfo.SellingPoint = in.SellingPoint
	spuInfo.MainImgUrl = in.MainImgUrl
	spuInfo.ImgUrls = in.ImgUrls
	spuInfo.Video = in.Video
	spuInfo.PriceFee = in.PriceFee
	spuInfo.MarketPriceFee = in.MarketPriceFee
	spuInfo.Status = 1
	spuInfo.HasSkuImg = int64(in.HasSkuImg)
	spuInfo.Seq = int64(in.Seq)
	spuInfo.CategoryName = in.CategoryName
	spuInfo.BrandName = in.BrandName
	spuInfo.CategoryName = in.CategoryName
	spuInfo.ShopCategoryName = in.ShopCategoryName
	spuInfo.ShopName = in.ShopName
	spuInfo.CreateTime = time.Now()
	spuInfo.UpdateTime = time.Now()
	var spuInfoId int64
	// 开启事务
	insertErr := l.svcCtx.DBEngin.Transaction(func(tx *gorm.DB) error {
		// 插入spu信息
		spuId, insertSpuInfoErr := spuMapper.Insert(l.ctx, tx, spuInfo)
		if insertSpuInfoErr != nil {
			return insertSpuInfoErr
		}
		// 保存商品其他信息，规格、详细
		var spuAttrValueArr []entity.SpuAttrValueEntity
		spuAttrValues := in.SpuAttrValues
		if len(spuAttrValues) == 0 {
			return excption.NewErrCode(constans.SpuAttrValueArrEmptyErr)
		}
		for _, v := range spuAttrValues {
			spuAttrValue := entity.SpuAttrValueEntity{}
			spuAttrValue.SpuId = spuId
			spuAttrValue.AttrId = v.AttrValueId
			spuAttrValue.AttrValueName = v.AttrValueName
			spuAttrValue.AttrName = v.AttrName
			spuAttrValue.AttrValueId = v.AttrValueId
			spuAttrValueArr = append(spuAttrValueArr, spuAttrValue)
		}
		spuAttrValueMapper := mapper.NewSpuAttrValueMapper()
		_, spuAttrValueErr := spuAttrValueMapper.BatchInsert(l.ctx, tx, spuAttrValueArr)
		if spuAttrValueErr != nil {
			return spuAttrValueErr
		}
		// detail
		detailEntity := entity.SpuDetailEntity{}
		detailEntity.SpuId = spuId
		detailEntity.Detail = in.Detail
		detailEntity.UpdateTime = time.Now()
		detailEntity.CreateTime = time.Now()
		detailMapper := mapper.NewSpuDetailMapper()
		_, insertDetailErr := detailMapper.InsertCtx(l.ctx, tx, detailEntity)
		if insertDetailErr != nil {
			return insertDetailErr
		}
		spuInfoId = spuId
		return nil
	})
	if insertErr != nil {
		return nil, insertErr
	}
	// 2.返回参数
	return &pb.SaveSpuVO{SpuId: spuInfoId}, nil
}
